using System;
using System.Collections;
using System.Collections.Generic;

namespace Me.Prettyprint.Hector.Api.Ddl
{
    /// <summary>
    /// Note: Nectar's implementation of ComparatorType has additional static maps
    /// to make it easier to use.
    /// </summary>
	public sealed class ComparatorType
	{
		public string ClassName
		{
			get
			{
				return className;
			}
			
		}
		public string TypeName
		{
			get
			{
				return typeName;
			}
			
		}
		public static readonly ComparatorType ASCIITYPE = new ComparatorType("org.apache.cassandra.db.marshal.AsciiType");
		public static readonly ComparatorType BOOLEANTYPE = new ComparatorType("org.apache.cassandra.db.marshal.BooleanType");
		public static readonly ComparatorType BYTESTYPE = new ComparatorType("org.apache.cassandra.db.marshal.BytesType");
        public static readonly ComparatorType COLLECTIONTYPE = new ComparatorType("org.apache.cassandra.db.marshal.CollectionType");
        public static readonly ComparatorType DATETYPE = new ComparatorType("org.apache.cassandra.db.marshal.DateType");
		public static readonly ComparatorType DECIMALTYPE = new ComparatorType("org.apache.cassandra.db.marshal.DecimalType");
        public static readonly ComparatorType DOUBLETYPE = new ComparatorType("org.apache.cassandra.db.marshal.DoubleType");
		public static readonly ComparatorType FLOATTYPE = new ComparatorType("org.apache.cassandra.db.marshal.FloatType");
		public static readonly ComparatorType INTEGERTYPE = new ComparatorType("org.apache.cassandra.db.marshal.IntegerType");
		public static readonly ComparatorType INT32TYPE = new ComparatorType("org.apache.cassandra.db.marshal.Int32Type");
		public static readonly ComparatorType LEXICALUUIDTYPE = new ComparatorType("org.apache.cassandra.db.marshal.LexicalUUIDType");
        public static readonly ComparatorType LISTTYPE = new ComparatorType("org.apache.cassandra.db.marshal.ListType");
        public static readonly ComparatorType LOCALBYPARTITIONERTYPE = new ComparatorType("org.apache.cassandra.db.marshal.LocalByPartionerType");
		public static readonly ComparatorType LONGTYPE = new ComparatorType("org.apache.cassandra.db.marshal.LongType");
        public static readonly ComparatorType MAPTYPE = new ComparatorType("org.apache.cassandra.db.marshal.MapType");
        public static readonly ComparatorType SETTYPE = new ComparatorType("org.apache.cassandra.db.marshal.SetType");
        public static readonly ComparatorType TIMEUUIDTYPE = new ComparatorType("org.apache.cassandra.db.marshal.TimeUUIDType");
		public static readonly ComparatorType UTF8TYPE = new ComparatorType("org.apache.cassandra.db.marshal.UTF8Type");
		public static readonly ComparatorType COMPOSITETYPE = new ComparatorType("org.apache.cassandra.db.marshal.CompositeType");
		public static readonly ComparatorType DYNAMICCOMPOSITETYPE = new ComparatorType("org.apache.cassandra.db.marshal.DynamicCompositeType");
		public static readonly ComparatorType UUIDTYPE = new ComparatorType("org.apache.cassandra.db.marshal.UUIDType");
		public static readonly ComparatorType COUNTERTYPE = new ComparatorType("org.apache.cassandra.db.marshal.CounterColumnType");
		public static readonly ComparatorType REVERSEDTYPE = new ComparatorType("org.apache.cassandra.db.marshal.ReversedType");

        private static readonly ComparatorType[] comparatorArray = new ComparatorType[] {
            ASCIITYPE, BOOLEANTYPE, BYTESTYPE, COLLECTIONTYPE, DATETYPE, DECIMALTYPE, DOUBLETYPE,
            FLOATTYPE, INTEGERTYPE, INT32TYPE, LEXICALUUIDTYPE, LISTTYPE, LOCALBYPARTITIONERTYPE,
            LONGTYPE, MAPTYPE, SETTYPE, TIMEUUIDTYPE, UTF8TYPE, COMPOSITETYPE, UUIDTYPE,
            COUNTERTYPE, REVERSEDTYPE};
        private static readonly Dictionary<string, ComparatorType> valuesMap = new Dictionary<string, ComparatorType>()
        {
            {ASCIITYPE.className, ASCIITYPE},
            {BOOLEANTYPE.className, BOOLEANTYPE},
            {BYTESTYPE.className, BYTESTYPE},
            {COLLECTIONTYPE.className, COLLECTIONTYPE},
            {DATETYPE.className, DATETYPE},
            {DECIMALTYPE.className, DECIMALTYPE},
            {DOUBLETYPE.className, DOUBLETYPE},
            {FLOATTYPE.className, FLOATTYPE},
            {INTEGERTYPE.className, INTEGERTYPE},
            {INT32TYPE.className, INT32TYPE},
            {LEXICALUUIDTYPE.className, LEXICALUUIDTYPE},
            {LISTTYPE.className, LISTTYPE},
            {LOCALBYPARTITIONERTYPE.className, LOCALBYPARTITIONERTYPE},
            {LONGTYPE.className, LONGTYPE},
            {MAPTYPE.className, MAPTYPE},
            {SETTYPE.className, SETTYPE},
            {TIMEUUIDTYPE.className, TIMEUUIDTYPE},
            {UTF8TYPE.className, UTF8TYPE},
            {COMPOSITETYPE.className, COMPOSITETYPE},
            {DYNAMICCOMPOSITETYPE.className, DYNAMICCOMPOSITETYPE},
            {UUIDTYPE.className, UUIDTYPE},
            {COUNTERTYPE.className, COUNTERTYPE},
            {REVERSEDTYPE.className, REVERSEDTYPE}
        };
		
		private string className;
		private string typeName;
		
		private ComparatorType(string className)
		{
			this.className = className;
			if (className.StartsWith("org.apache.cassandra.db.marshal."))
			{
				typeName = className.Substring("org.apache.cassandra.db.marshal.".Length);
			}
			else
			{
				typeName = className;
			}
		}
		
		public static ComparatorType getByClassName(string className)
		{
			if (className == null)
			{
				return null;
			}
            if (className.StartsWith("org.apache.cassandra.db.marshal.CompositeType") && className.IndexOf('(') > 1)
            {
                className = "org.apache.cassandra.db.marshal.CompositeType";
            }
            ComparatorType type = null;
            if (!valuesMap.ContainsKey(className))
            {
                ComparatorType t = new ComparatorType(className);
                valuesMap[t.className] = t;
            }
            else
            {
                type = valuesMap[className];
            }
			return type;
		}
		public override int GetHashCode()
		{
			return className.GetHashCode();
		}
		public override bool Equals(System.Object obj)
		{
			if (this == obj)
			{
				return true;
			}
			if (obj == null)
			{
				return false;
			}
			if (GetType() != obj.GetType())
			{
				return false;
			}
			ComparatorType other = (ComparatorType) obj;
			if (!className.Equals(other.className))
			{
				return false;
			}
			return true;
		}
		static ComparatorType()
		{
			{
				ComparatorType[] types = new ComparatorType[]{ASCIITYPE, BOOLEANTYPE, BYTESTYPE, DATETYPE, DECIMALTYPE, FLOATTYPE, INTEGERTYPE, INT32TYPE, LEXICALUUIDTYPE, LOCALBYPARTITIONERTYPE, LONGTYPE, TIMEUUIDTYPE, UTF8TYPE, COMPOSITETYPE, DYNAMICCOMPOSITETYPE, UUIDTYPE, COUNTERTYPE, REVERSEDTYPE};
				Dictionary<string,ComparatorType > builder = new Dictionary<string,ComparatorType>();				
				foreach (ComparatorType type in types)
				{
					builder.Add(type.ClassName, type);
                    builder.Add(type.TypeName, type);
				}
                valuesMap = builder;
			}
		}
	}
}